package kgame5.k3d.core.obj3d.node3d.group3d {
import kgame5.k3d.core.obj3d.node3d.Group3D;
import kgame5.k3d.core.obj3d.node3d.Node3D;
import kgame5.k3d.core.render.RenderSessionData;
import kgame5.k3d.core.render.layerrender.impl.Group3DLayerRender;

import flash.display.Sprite;
import flash.utils.getTimer;

/**
 * @author kk
 * 对每个模型进行排序
 */
public class GoodGroup3D extends Group3D{
	
	public static const 
		SORTMODE_CCD2:int=1,//只根据ccz排序，这个就按照一个字段排序，在as2里比按2个字段排序要快得多
		SORTMODE_CCD2_BORNID:int=2;//根据ccz和出生id排序,默认的

	//_____________________Property_________________________
	
	private var aSort:Array=null;//对child进行排序
	
	//--排序选项，这个是很重要的，会消耗很多cpu!
	private var sortMode:int=0;
	
	private var mc:Sprite;
	
	
	//______________________Method__________________________
	//p_sortLayer是是否参与排序,sortType是自己排序内部的东西
	public function GoodGroup3D(p_sortMode:int=1){//sortType=2是ccz_bornID
		super();
		
		sortMode=p_sortMode;
		aSort=new Array();
		
		//-这样主要是FastGroup3D和GoodGroup3D用的
		renderer=new Group3DLayerRender();	
		mc=renderer.getDO() as Sprite;
		
	}
	
	
	
	//------针对child列表的操作
	override public function addChild(md:Node3D):void{
		
		//-
		super.addChild(md);
		
		//aSort添加
		aSort.push(md);
		
		//视图
		mc.addChild(md.getDO());//放在需要排序的图层
	}
	
	//删除，操作是从2个数组里删掉，并不dispose,只是从显示列表中移开而已
	override public function removeChild(md:Node3D):void{
		
		//-
		super.removeChild(md);
		
		//aSort删除
		for(var i:int=aSort.length-1;i>=0;i--){
			if(aSort[i]==md){
				aSort.splice(i,1);
				break;
			}
		}	
		//视图删除mc
		try{
			mc.removeChild(md.getDO());
		}catch(e:Error){
			//这个不存在，不能删除
		}
	}
	
	override public function removeAllChild():void{
		//-视图删除
		for each(var md:Node3D in aChild){
			mc.removeChild(md.getDO());
		}
		//-
		super.removeAllChild();
		//-
		aSort=new Array();
	}
	
	override public function Update(rsd:RenderSessionData,isParentDirty:Boolean):void{
		//--
		if(isVisible()==false){
			return ;
		}
		
		//--
		ti.calcMoc_Full(parentNode.ti.Mow,rsd.Mwc, rsd.isMwcDirty,isParentDirty);
		
		//--
		mc.visible=true;
		
		//--
		var bNeedSort:Boolean=rsd.isMwcDirty;//是否需要排序，开始的时候是根据摄象机是否动了来判断的
		
		//--各个模型
		for each(var md:Node3D in aChild){
			
			md.Update(rsd, this.ti.isNeedRedraw);//经过优化的更新方式,只能绕y轴旋转
			
			//设置好ccd.不管是否md.ti.isNeedSort,这个都需要记录，因为可能是摄像机动了呢！
			md.ccd2=md.ti.ccd2;//这个要放在update之后即可，否则会有错误的!!
			
			if(md.ti.isNeedSort) {
				//位置是否变化了，只有位置变化才会影响到排序呢
				//!!注意，这里有漏洞，当我做一个球总是旋转的时候，就会导致排序失效~
				bNeedSort=true;//注意初始值是Mwc是否变化
			}
		}
		
		//--执行排序,这个是排MovieClip的序，需要在其他都计算完了之后才执行这个
		if(bNeedSort){//!!这个优化机制很重要，就是摄象机，所有模型都没动的时候，不去排序深度，能把cpu从13%降到3~4%！！
			sortNode(rsd);
		}
	}
	
	private const SORT_MODE_X:int=Array.DESCENDING|Array.NUMERIC;
	private const SORT_FEILD:Array=["ccd2","bornID"];
	private const SORT_MODE:Array=[Array.DESCENDING|Array.NUMERIC,Array.NUMERIC];
	//！！严重注意这个操作100个mc会排序占到2+8=10ms的cpu!!,所以不需要排序的时候还是不要排序为好
	protected function sortNode(session:RenderSessionData):void{
		var st:int=getTimer();
		//只有一个模型，或者没有模型，则不需要排序了就
		if(this.aSort.length<= 1) {
			return;
		}
		
		//这个排序，1600个模型是2ms
		switch(sortMode){
			case SORTMODE_CCD2://一段排序比2段排序要快一倍,这个只是不好处理同样2个卡片在同一层级的情况
			aSort.sortOn("ccd2",SORT_MODE_X);
			break;
			case SORTMODE_CCD2_BORNID://用sortOn做2段排序比一段要慢，sort(order)比sortOn要慢
			aSort.sortOn(SORT_FEILD,SORT_MODE);
			break;
		}
		
		//------老式的
		var len:int=aSort.length;
		
		for(var i:int=0;i<len;i++){
			var md:Node3D=aSort[i] as Node3D;
			
			//mc.setChildIndex(md.getDO(),i);//这么用时1600个物体是50+
			mc.addChild(md.getDO());//这么用时1600个物体是40~45
		}
		
		session.stati.sortNodeTime += getTimer()-st;
	}
}//end of class
}